<template>
	<view><canvas canvas-id="mSetimg" :style="{width: canvasWH.width + 'px', height: canvasWH.height + 'px'}" class="my-canvas"
	        disable-scroll="false"></canvas></view>
</template>

<script>
export default {
	props: {
		type: {
			type: Number,
			default: 1
		},
        canvasWH: {
            type: Object,
            default: function() {
                return {
                    width: 750,
                    height: 1334,
                    bgcolor: ''
                }
            }
        }
	},
	created() {
		this.ctxCanvas = uni.createCanvasContext('mSetimg', this);
	},
	methods: {
		haibao(calData, callback) {
            uni.showLoading({
                title: '加载中', //文字
                mask: true //是否全局遮罩
            })
			this.image('mSetimg', calData.imgList, calData.textList, callback);
		},
		image(canvasId, imgList, textList, callback) {
            let _that = this;
			let ctx = this.ctxCanvas;
			let promiseAll = [];
			for (let v of imgList) {
				promiseAll.push(this.downloadImg(v));
			}
			Promise.all(promiseAll)
				.then(res => {
					for (let i = 0; i < res.length; i++) {
						this.drawImg(imgList[i], res[i]);
					}
					this.setFont(textList);
					ctx.draw(false, res => {
						setTimeout(() => {
							uni.canvasToTempFilePath(
								{
									canvasId: canvasId,
									width: _that.canvasWH.width,
									height: _that.canvasWH.height,
									destWidth: _that.canvasWH.width,
									destHeight: _that.canvasWH.height,
									quality: 1,
									success: function(res) {
										callback(res.tempFilePath);
									},
									fail: function(res) {
										console.log(JSON.stringify(res));
									},
									complete: res => {
										uni.hideLoading();
									}
								},
								this
							);
						}, 200);
					});
				})
				.catch(() => {
					uni.hideLoading();
				});
		},
		// 获取网络图片
		downloadImg(item) {
			return new Promise((resolve, reject) => {
				uni.downloadFile({
					url: item.u,
					success: res => {
						if (res.statusCode === 200) {
							resolve(res);
						}
					},
					fail: (err) => {
                        uni.showModal({
                            content: `${JSON.stringify(item)}`
                        })
						uni.showToast({
							title: '网络异常，请重试',
							icon: 'none'
						});
						reject(err);
					}
				});
			});
		},
		// 绘图
		drawImg(item, res) {
			let ctx = this.ctxCanvas;
			if (item.PI) {
				ctx.save();
				ctx.beginPath();
				ctx.arc(item.x + item.w / 2, item.y + item.w / 2, item.w / 2, 0, 2 * Math.PI);
				ctx.stroke();
				ctx.clip();
				ctx.drawImage(res.tempFilePath, item.x, item.y, item.w, item.h);
				ctx.restore();
			} else {
				if (item.circle) {
					ctx.save();
					ctx.beginPath();
					ctx.arc(item.x + item.w / 2, item.y + item.h / 2, item.r, 0, 2 * Math.PI);
					ctx.setStrokeStyle('#E9E9E9');
					ctx.stroke();
					ctx.clip();
					ctx.drawImage(res.tempFilePath, item.x, item.y, item.w, item.h);
					ctx.restore();
				} else {
					ctx.drawImage(res.tempFilePath, item.x, item.y, item.w, item.h);
				}
			}
		},
		//绘制文字
		setFont(arr) {
			let _this = this;
			let ctx = this.ctxCanvas;
			let s = 20 * this.scale; //默认字体大小
			let f = 'normal normal 20px/20px sans-serif';
			arr.forEach((item, index) => {
				ctx.setTextBaseline('top');
				ctx.font = item.f || f;
				ctx.setFontSize(item.s || s);
				ctx.setTextAlign(item.setTextAlign || 'left');
				ctx.setFillStyle(item.strokeStyle || '#000000');
				if (item.setShadow) {
					ctx.setShadow(...item.setShadow);
				} else {
					ctx.setShadow(0, 0, 0, '#000000');
				}
				let textWidth = this.getStringWidth(item.t, item.s || s);
				if (item.maxWidth) {
					if (textWidth <= item.maxWidth) {
						ctx.fillText(item.t, item.x, item.y);
					} else {
						this.wordWrap(item.t, item.s, item.x, item.y, item.maxWidth);
					}
				} else {
					ctx.fillText(item.t, item.x, item.y);
				}
				if (item.lineThrough) {
					this.drawLineThrough(item.x, item.y, textWidth, '#989898', item.s || s);
				}
				if (item.b) {
					item.b.bind(_this)({ x: item.x / 1 + 5, y: item.y, w: textWidth });
				}
			});
		},
		// 绘制文字换行
		wordWrap(t, s, x, y, m) {
			let chr = t.split(''); // 分割为字符串数组
			let temp = '';
			let row = [];
			for (let a = 0; a < chr.length; a++) {
				let tempWidth = this.getStringWidth(temp, s);
				if (tempWidth < m) {
					temp += chr[a];
				} else {
					a--;
					row.push(temp);
					temp = '';
				}
			}
			row.push(temp);
			for (var b = 0; b < row.length; b++) {
				if (b < row.length) {
					this.ctxCanvas.fillText(row[b], x, y + b * s * 1.5);
				}
			}
		},
		// 获取文本宽度兼容方法
		measureTextWidth(t, s) {
			t = String(t);
			let arr = t.split('');
			let width = 0;
			arr.forEach(function(item) {
				if (/[a-zA-Z]/.test(item)) {
					width += 7;
				} else if (/[0-9]/.test(item)) {
					width += 5.5;
				} else if (/\./.test(item)) {
					width += 2.7;
				} else if (/-/.test(item)) {
					width += 3.25;
				} else if (/[\u4e00-\u9fa5]/.test(item)) {
					//中文匹配
					width += 10;
				} else if (/\(|\)/.test(item)) {
					width += 3.73;
				} else if (/\s/.test(item)) {
					width += 2.5;
				} else if (/%/.test(item)) {
					width += 8;
				} else if (/#|¥/.test(item)) {
					width += 6.4;
				} else if (/\?|\*/.test(item)) {
					width += 4.9;
				} else if (/\!|\_/.test(item)) {
					width += 4.5;
				} else if (/\+|\=|\^|~/.test(item)) {
					width += 7.7;
				} else if (/\[|\]/.test(item)) {
					width += 3.9;
				} else if (/:/.test(item)) {
					width += 2.9;
				} else {
					width += 10;
				}
			});
			return (width * s) / 10;
		},
		// 获取文字长度兼容写法
		getStringWidth(t, s) {
			let textWidth = 0;
			try {
				textWidth = this.ctxCanvas.measureText(t).width || this.measureTextWidth(t, s);
			} catch (err) {
				textWidth = s * t.length;
			}
			return textWidth;
		},
		// 绘制线条
		drawLineThrough(x, y, w, color, size) {
			let top = 0;
			let ctx = this.ctxCanvas;
			// #ifdef APP-PLUS
			top = y / 1 + size / 2 + 1;
			// #endif
			// #ifndef APP-PLUS
			top = y / 1 + size / 2;
			// #endif
			ctx.beginPath();
			ctx.setLineWidth(1);
			ctx.moveTo(x, top);
			ctx.lineTo(x + w, top);
			ctx.setStrokeStyle(color);
			ctx.stroke();
		}
	}
};
</script>

<style lang="scss" scoped>
.my-canvas {
	position: fixed;
	top: 10000px;
	left: 10000px;
	width: 750px;
	height: 1334px;
}
</style>